﻿using System.Windows.Controls;
using System.Windows.Media;

namespace DimensionsHelper.Client.Controls;

public class BorderGrid : Grid
{
    public static readonly DependencyProperty BorderThicknessProperty =
        DependencyProperty.Register(
            nameof(BorderThickness),
            typeof(double),
            typeof(BorderGrid),
            new PropertyMetadata(1d));


    public static readonly DependencyProperty BorderBrushProperty =
        DependencyProperty.Register(
            nameof(BorderBrush),
            typeof(Brush),
            typeof(BorderGrid),
            new PropertyMetadata(Brushes.LightGray));


    public static readonly DependencyProperty StrokeDashArrayProperty =
        DependencyProperty.Register(
            nameof(StrokeDashArray),
            typeof(DoubleCollection),
            typeof(BorderGrid),
            new PropertyMetadata(null));


    public BorderGrid()
    {
        Ranges = new BorderGridRangeCollection(this);
        Initialized += OnBorderInitialized;
    }


    public double BorderThickness
    {
        get => (double)GetValue(BorderThicknessProperty);
        set => SetValue(BorderThicknessProperty, value);
    }


    public Brush BorderBrush
    {
        get => (Brush)GetValue(BorderBrushProperty);
        set => SetValue(BorderBrushProperty, value);
    }


    public DoubleCollection? StrokeDashArray
    {
        get => GetValue(StrokeDashArrayProperty) as DoubleCollection;
        set => SetValue(StrokeDashArrayProperty, value);
    }


    public BorderGridRangeCollection Ranges { get; set; }


    protected override int VisualChildrenCount => base.VisualChildrenCount + Ranges.CellsCount;


    protected override Visual GetVisualChild(int index)
    {
        int baseCount = base.VisualChildrenCount;
        return index >= baseCount ? Ranges.GetCell(index - baseCount) : base.GetVisualChild(index);
    }


    private void OnBorderInitialized(object? sender, EventArgs e)
    {
        Initialized -= OnBorderInitialized;
        Ranges.Initialize(this);

        foreach (BorderGridRange? range in Ranges.Cast<BorderGridRange>())
        {
            Children.Add(range);

            foreach (BorderGridRange? childRange in range.Cast<BorderGridRange>())
            {
                Children.Add(childRange);
            }
        }
    }


    protected override Size ArrangeOverride(Size arrangeSize)
    {
        Size size = base.ArrangeOverride(arrangeSize);
        Ranges.UpdateBorder();
        return size;
    }
}